package gov.nasa.anml.lifted;

import java.util.*;

import gov.nasa.anml.utility.Pair;
import gov.nasa.anml.utility.SimpleObject;

public class Enumeration<T extends Comparable> implements Constraint<T> {

	// could have holes, unlike Range
	public Set<T> values = new HashSet<T>();
	// least over(upper)-approximating interval (lub)
	public Pair<T,T> bounds;

	public Enumeration() {
	}
	
	public Enumeration(Set<T> v) {
		values = v;
	}
	
	void setBounds() {
		Set<T> v = values;
		if (v != null) {
			T min, max;
			Iterator<T> i = v.iterator();
			if (i.hasNext()) {
				min=max=i.next();
				while(i.hasNext()) {
					T a = i.next();
					if (a.compareTo(min) < 0)
						min = a;
					else if (a.compareTo(max) > 0)
						max = a;
				}
				bounds = new Pair<T,T>(min,max);
			}
		}
	}

	public boolean containsAll(Constraint<T> t) {
		Set<T> v = t.values();
		if (v == null) 
			return false;
		Pair<T,T> b = t.bounds();
		if (b != null) {
			Pair<T,T> a = bounds();
			if (a.left.compareTo(b.left) > 0)
				return false;
			if (a.right.compareTo(b.right) < 0)
				return false;
		}
		return values.containsAll(v);
	}

	public Set<T> values() {
		return values;
	}

	public Pair<T,T> bounds() {
		if (bounds == null)
			setBounds();
		return bounds;
	}

	public boolean add(T e) {
		return values.add(e);
	}

	public boolean addAll(Collection<? extends T> c) {
		return values.addAll(c);
	}

	public void clear() {
		values.clear();
	}

	public boolean equals(Object o) {
		return values.equals(o);
	}

	public int hashCode() {
		return values.hashCode();
	}

	public boolean isEmpty() {
		return values.isEmpty();
	}

	public Iterator<T> iterator() {
		return values.iterator();
	}

	public boolean remove(Object o) {
		return values.remove(o);
	}

	public boolean removeAll(Collection<?> c) {
		return values.removeAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return values.retainAll(c);
	}

	public int size() {
		return values.size();
	}

	public Object[] toArray() {
		return values.toArray();
	}

	public <T> T[] toArray(T[] a) {
		return values.toArray(a);
	}

	public boolean contains(Object o) {
		return values.contains(o);
	}

	public boolean containsAll(Collection<?> c) {
		return values.containsAll(c);
	}
	
	public Enumeration<T> clone() {
		Enumeration<T> c = null;
		try {
			c = (Enumeration<T>) super.clone();
		} catch (CloneNotSupportedException e) {
			//assert false;
		}
		c.values = new HashSet<T>(values);
		return null;
	}

}
